package com.caul.demo.hadoop.hdfs.model;

import com.caul.demo.hadoop.hdfs.Cmd;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by sdliang on 2018/3/28.
 */
public class MetaData {

  private String fileName;
  private List<BlockData> blocks;

  public String getFileName() {
    return fileName;
  }

  public void setFileName(String fileName) {
    this.fileName = fileName;
  }

  public List<BlockData> getBlocks() {
    return blocks;
  }

  public void setBlocks(List<BlockData> blocks) {
    this.blocks = blocks;
  }

  public void addBlock(BlockData block) {
    if (getBlocks() == null) {
      setBlocks(new ArrayList<>());
    }
    getBlocks().add(block);
  }

  /**
   * @param str "fileName:blockId|datanode|blockLen,..."
   * @return
   */
  public static MetaData of(String str) {
    if (str == null) {
      return null;
    }
    MetaData resp = new MetaData();
    String[] blockAndNode = str.split(Cmd.SPLIT_CMD);
    resp.setFileName(blockAndNode[0]);

    String[] blocksAry = blockAndNode[1].split(Cmd.SPLIT_META);
    for (String blockStr : blocksAry) {
      String[] block = blockStr.split(Cmd.SPLIT_BLOCK);
      resp.addBlock(new MetaData.BlockData(block[0], block[1], Long.parseLong(block[2])));
    }
    return resp;
  }

  public String value() {
    StringBuilder nodes = new StringBuilder();
    getBlocks().forEach(block -> nodes.append(Cmd.SPLIT_META).append(block.value()));
    return String.format(Cmd.NN_UPLOAD_RESP, getFileName(), nodes.substring(1));
  }

  public static class BlockData {

    private String blockId;
    private String dataNode;
    private long blockStart;
    private long blockLen;

    public BlockData(String blockId, String dataNode, long blockLen) {
      this.blockId = blockId;
      this.dataNode = dataNode;
      this.blockLen = blockLen;
    }

    public BlockData(String blockId, String dataNode) {
      this.blockId = blockId;
      this.dataNode = dataNode;
      this.blockLen = Cmd.BLOCK_SIZE;
    }

    public String getBlockId() {
      return blockId;
    }

    public void setBlockId(String blockId) {
      this.blockId = blockId;
    }

    public String getDataNode() {
      return dataNode;
    }

    public void setDataNode(String dataNode) {
      this.dataNode = dataNode;
    }

    public long getBlockLen() {
      return blockLen;
    }

    public void setBlockLen(long blockLen) {
      this.blockLen = blockLen;
    }

    public long getBlockStart() {
      return blockStart;
    }

    public void setBlockStart(long blockStart) {
      this.blockStart = blockStart;
    }

    public String value() {
      return String.format(Cmd.INFO_BLOCK, getBlockId(), getDataNode(), getBlockLen());
    }
  }
}
